<?php
namespace Common\Model;

class PlanStatsModel extends Model {
    protected $tableName = 'template.plan_stats';
    protected $viewName  = 'v_plan_stats';

    public function setTrueTableNameByDay($day = null) {
        $timestamp = ($_d = strtotime($day)) ? $_d : time();
        $schema = 'd' . date('Ymd', $timestamp);

        return $this->trueTableName = $schema . '.' . $this->viewName;
    }

    /**
     * _parseOptions
     * 拦截_parseOptions主要是为了自动生成表名
     * 生成表名时必须用到的参数有day,也就是where()的条件必须要有day
     *
     * @param mixed $options
     * @return void
     */
    protected function _parseOptions($options = null) {
        if(!empty($this->options['where']['day']) || empty($this->trueTableName) || ($this->trueTableName == $this->tableName)) {
            $day = empty($this->options['where']['day']) ? null : $this->options['where']['day'];

            if(empty($day)) {
                throw new \Exception('请确认是否有day');
            }

            if($this->options['where']['day'][0] == 'between') {
                $this->parseDayBetween($this->options);
            } else {
                $timestamp  = strtotime($day);
                $tableName  = 'd' . date('Ymd', $timestamp) . '.' . $this->viewName;
                $options    = array_merge($options, array('table' => $tableName));

                $this->trueTableName = $tableName;

                unset($options['where']['day']);    //v_plan_stats中无day字段，用day主要是定位到对应日期的表上
            }
        }

        return parent::_parseOptions($options);
    }

    /**
     * parseDayBetween
     * 分解day中的between条件
     *
     * @param mixed $options
     * @return void
     */
    protected function parseDayBetween(&$options) {
        $startDay       = $options['where']['day'][1][0];
        $endDay         = $options['where']['day'][1][1];
        $startTimestamp = strtotime($startDay);
        $endTimestamp   = strtotime($endDay);
        $startMonth = date('Ym01', $startTimestamp);
        $endMonth = date('Ym01', $endTimestamp);
        $tmpTimestamp   = $startTimestamp;
        $tmpMonth = date('Ym01', $tmpTimestamp);

        if($startMonth == $endMonth) {
            $table  = 'm' . date('Ym', $tmpTimestamp) . '.plan_stats';
            $tmpDay = date('Y-m-d', $tmpTimestamp);

            $options['table'] = $table;
            $this->trueTableName = $table;

            return true;
        }

        $order = $options['order'];
        $field = $options['field'];
        $limit = $options['limit'];
        unset($options['order']);
        unset($options['limit']);
        $distOptions      = $options;
        $firstExistsMonth = '';

        while(strtotime($tmpMonth) <= strtotime($endMonth)) {
            $tmpOptions = $distOptions;
            $tmpMonth   = date('Ym01', $tmpTimestamp);
            $schema     = 'm' . date('Ym', $tmpTimestamp);
            $table      = 'plan_stats';
            $tmpDay     = date('Y-m-d', $tmpTimestamp);

            /**
             * 检测表格是否存在，如果不存在则忽略
             */
            if(!checkTableIsExists($table, $schema)) {
                $tmpTimestamp = strtotime('+1 month', $tmpTimestamp);
                $tmpMonth     = date('Ym01', $tmpTimestamp);

                continue;
            }

            /**
             * 找出对应月份存在表格的月份，用于后面重置$options['where']['day']表达式
             */
            if(empty($firstExistsMonth)) {
                $firstExistsMonth = $tmpMonth;
            }

            $table = $schema . '.' . $table;

            /**
             * 第一个判断中的条件做为buildSelectSql()中原始条件
             */
            if($tmpMonth == $startMonth || $tmpMonth == $firstExistsMonth) {
                $options['table'] = $table;
                $options['where']['day'] = array('EGT', $startDay);
                $this->trueTableName = $table;
            } elseif($tmpMonth == $endMonth) {
                $tmpOptions['table'] = $table;
                $tmpOptions['where']['day'] = array('ELT', $endDay);
                $sql = $this->db->buildSelectSql($tmpOptions);
            } else {
                $tmpOptions['table'] = $table;
                unset($tmpOptions['where']['day']);
                $sql = $this->db->buildSelectSql($tmpOptions);
            }

            $tmpTimestamp = strtotime('+1 month', $tmpTimestamp);
            $tmpMonth     = date('Ym01', $tmpTimestamp);

            if(!empty($sql)) {
                $this->union($sql, 1);
            }
        }

        $sql = $this->db->buildSelectSql($options);
        $this->options = array(
            'table' => "({$sql}) AS a",
            'field' => $field,
            'order' => $order,
            'limit' => $limit,
            'group' => empty($tmpOptions['group']) ? '' : $tmpOptions['group'],
        );
    }

    protected function _options_filter(&$options) {
        if(!$loginUser = C('RUN_LOGIN_USER')) {
            exit('NO LOGIN');
        }

        /**
         * 为广告主平台数据绑定广告主编号
         */
        if($loginUser['type'] == 2) {
            $options['where']['uid'] = $loginUser['id'];

            return true;
        }
    }

    /**
     * buildSearchExpr 
     * 组装查询条件
     * 
     * @param mixed $d  查询数据，一般来源于$_GET或$_POST
     * @param mixed $field  可查询的字段对照表，其结构为array(array('表单项目名称' => '数据库字段名称'))
     * @access public
     * @return void 返回值为数组，参见方法内部注释
     */
    public function buildSearchExpr($d, $field = NULL) {
        $expr = array();
        $dao  = array();
        $sortExpr = 'day DESC, num DESC';

        /**
         * 下标为表单中的项目名称，值为数据库中表的字段名称 
         */
        if(empty($field)) {
            $field  =   array(
                'day'         => 'day',
                'day2'        => 'day',
                'plan_id'     => 'plan_id',
                'plan_name'   => 'plan_name',
                'plan_type'   => 'plan_type',
                'uid'         => 'uid',         //广告主编号
                'plan_status' => 'plan_status',
                'tag'         => '',
            );
        }

        $day  = empty($d['day'])  ? date('Y-m-d') : trim($d['day']);
        $day2 = empty($d['day2']) ? null          : trim($d['day2']);

        if(!empty($day)) {
            if(!empty($day2)) {
                $a = strtotime($day);
                $b = strtotime($day2);

                if($a > $b) {
                    $day2 = $day;
                    $day  = date('Y-m-d', $b);
                }

                $expr['day'] = array('between', array($day, $day2));
            } else {
                $expr['day'] = $day;
            }
        }

        foreach($field as $k => $v) {
            $tmpExpr = null;
            $val     = isset($d[$k]) ? trim($d[$k]) : '';

            if(is_string($val) && strlen($val) < 1) {
                continue;
            }

            if($k == 'plan_name') {
                $expr[$v] = array('EXP', " LIKE '%{$val}%'");
            } elseif($k == 'plan_type') {
                $expr[$v] = strtolower($val);
            } elseif(in_array($k, array('day', 'day2'))) {


            /**
             * plan_stats在t_plan_stats中表不存在，如果直接以$expr['plan_status']指定条件则会被ThinkPHP过滤掉
             * 但是以_string的方式指定则不会被过滤
             */
            } elseif($k == 'plan_status') { 
                $tmpExpr = "plan_status = {$val}";
            } elseif ($k == 'tag') {
/**
 * 不改动v_plan_stats视图结构加入tag_id字段，所以在此处将tag条件转化成plan_id条件
 */
                $_planModel = D2('Plan');
                $_ids       = [];

                if ($_planRecords = $_planModel->field('planid AS plan_id')->where(['tag_id' => ['in', $d[$k]]])->select()) {
                    foreach ($_planRecords as $_row) {
                        $_ids[] = $_row['plan_id'];
                    }
                }

                if (!empty($_ids)) {
                    $expr['plan_id'] = ['in', $_ids];
                }
            } else {
                $expr[$v] = $d[$k];
            }

            if(!empty($tmpExpr)) {
                $expr['_string'] = empty($expr['_string'])
                                  ? $tmpExpr
                                  : $expr['_string'] . " AND {$tmpExpr}";
            }

            $dao[$k] = $d[$k];
        }

        if(empty($expr['day'])) {
            $expr['day'] = date('Y-m-d');
            $dao['day']  = $expr['day'];
        }

        $sortField   = $this->getDbFields();
        $sortField[] = 'plan_status';

        if(!empty($d['sort']) && in_array($d['sort'], $sortField)) {
            $sortdir = empty($d['sortdir'])                     ? 'DESC'   : strtoupper($d['sortdir']);
            $sortdir = in_array($sortdir, array('DESC', 'ASC')) ? $sortdir : 'DESC';

            $sortExpr       = "{$d['sort']} {$sortdir}";
            $dao['sort']    = $d['sort'];
            $dao['sortdir'] = $sortdir;
        }

        if(empty($expr) && empty($dao)) {
            return false;
        }

        return array(
            'expr' => $expr,            //ThinkPHP查询条件表达式
            'sort' => $sortExpr,        //排序表达式
            'json' => json_encode($dao) //用于回填至查询表单的数据
        );
    }

    /**
     * getCost
     * 获取计划在指定日期的已消费金额
     *
     * @param mixed $planId
     * @param mixed $day
     * @return void
     */
    public function getCost($planId, $day = null) {
        $planId = (int)$planId;
        $day    = empty($day)   ? date('Y-m-d') : $day;
        $expr   = array('plan_id' => $planId, 'day' => $day);

        return $this->where($expr)->getField('ader_pay');
    }

}
